package cn.itcast.bos.utils;

import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 * @author WBH 约定属性和Excel表格中的对应关系 。比如： Excel表格中 列数1,2,3分别对应
 *         {id,username,password} 本次工具类抽取没有进行类型判断
 * 
 *         还有一种处理方式： 将Excel 每行记录的数据和Bean的属性名做个Map<String,String> map = new
 *         HashMap<BeanFieldName,cellValue>. 然后将map通过BeanUtils.populate()做数据封装
 * 
 */
public class ExcelUtil {
	/**
	 * @param path
	 *            excel文件路径
	 * @param clazz
	 *            要封装的实体类Class对象
	 * @param args
	 *            字段名称
	 */
	public static List importXls(File file,String fileName, Class clazz, String... args) {
		List<Object> list = new ArrayList<Object>();
		try {
			// 返回结果数据集合
			Sheet sheet = getExcelSheetByFile(file,fileName);
			for (Row row : sheet) {
				if (row.getRowNum() > 0) {
					Object realObj = clazz.newInstance();
					for (int i = 0; i < args.length; i++) {// 传入的参数列表进行遍历"id","username","gender"
						// 读取Cell
						Field field = clazz.getDeclaredField(args[i]);
						field.setAccessible(true);
						// field.getType();
						Cell cell = row.getCell(i);// 得到当前行的第i+1个Cell
						String cellValue = getCellStringValue(cell);// 此处将所有类型都转换成了字符串进行处理
						field.set(realObj, cellValue);
					}
					list.add(realObj);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

	/**
	 * 获取表格内数据
	 * 
	 * @param cell
	 * @return
	 */
	private static String getCellStringValue(Cell cell) {
		String cellValue;
		switch (cell.getCellType()) {
		case Cell.CELL_TYPE_NUMERIC: // 数字
			cellValue = (int) cell.getNumericCellValue() + "";
			break;

		case Cell.CELL_TYPE_STRING: // 字符串
			cellValue = cell.getStringCellValue();
			break;

		case Cell.CELL_TYPE_BOOLEAN: // Boolean
			cellValue = cell.getBooleanCellValue() + "";
			break;

		case Cell.CELL_TYPE_FORMULA: // 公式
			cellValue = cell.getCellFormula() + "";
			break;

		case Cell.CELL_TYPE_BLANK: // 空值
			cellValue = "";
			break;

		case Cell.CELL_TYPE_ERROR: // 故障
			cellValue = "非法字符";
			break;
		default:
			cellValue = "未知类型";
			break;
		}
		return cellValue;
	}

	/**
	 * 根据不同的文件后缀名得到不同版本的Workbook对象,返回其sheet对象
	 * 
	 * @param filePath
	 * @return
	 * @throws Exception
	 */
	public static Sheet getExcelSheet(String filePath) throws Exception {
		// 1、加载Excel文件
		Workbook workbook = null;
		if (filePath.matches("^.+\\.(?i)(xls)$")) {
			workbook = new HSSFWorkbook(new FileInputStream(filePath));// xls后缀
		} else if (filePath.matches("^.+\\.(?i)(xlsx)$")) {
			workbook = new XSSFWorkbook(new FileInputStream(filePath));//
		}
		// 2、加载第一个sheet页
		Sheet sheet = workbook.getSheetAt(0);
		return sheet;
	}

	// 【我的补充】根据后缀名来确定excel的版本
	public static Sheet getExcelSheetByFile(File file, String fileName) {
		Workbook workbook = null;
		try {
			// 1、加载Excel文件

			// 表达式的结尾处的不区分大小写 i 标记指定不区分大小写。

			if (fileName.matches("^.+\\.(?i)(xls)$")) {
				workbook = new HSSFWorkbook(new FileInputStream(file));// xls后缀
			} else if (fileName.matches("^.+\\.(?i)(xlsx)$")) {
				workbook = new XSSFWorkbook(new FileInputStream(file));//
			}
			// 2、加载第一个sheet页
			Sheet sheet = workbook.getSheetAt(0);
			return sheet;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}
